package com.upf1sh.service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.upf1sh.bean.FileEntity;
import com.upf1sh.common.FileUploadUtils;
import com.upf1sh.common.ServerConfigs;
import com.upf1sh.mapper.FileMapper;
import com.upf1sh.utils.JwtUtils;
import com.upf1sh.utils.user_info;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.*;

/**
 * UpF1sh
 * 2023/4/13
 * 完善，精简file controller
 */
@Service
public class FileService {
    @Resource
    private FileMapper fileMapper;
    @Autowired
    private com.upf1sh.common.upf1sh upf1sh;

    @Autowired
    private ServerConfigs serverConfigs;

    /**
     * 添加文件到数据库
     * UpF1sh
     * 2023/4/18 11:14
     */

    public boolean insertFile(@RequestBody FileEntity file_entity) {
        return fileMapper.insert(file_entity) == 1 ? true : false;
    }

    /**
     * 删除数据库中文件信息
     * UpF1sh
     * 2023/4/18 11:22
     *
     * @param path
     * @return
     */
    public boolean deleteFile_db(String path) {
        return fileMapper.deleteFile_entity(path) > 0 ? true : false;
    }


    // 线程池配置
    private static final ExecutorService executorService = new ThreadPoolExecutor(
            4, // 核心线程数
            5, // 最大线程数
            60L, // 超时时间
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100), // 缓冲队列
            new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
    );
    @Transactional
    public String uploadNew(MultipartFile file, String username) throws IOException {


        String filePath = upf1sh.getUploadPath();
        String url1 = serverConfigs.getUrl();

        // 使用异步线程执行文件上传
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                String fileName = FileUploadUtils.upload(filePath, file);
                String url = url1  + fileName;
                System.out.println("url"+url);
                return url;
            } catch (IOException e) {
                return e.getMessage();
            }
        }, executorService);

        try {
            // 获取异步结果，设置超时时间 10s
            return future.get(10, TimeUnit.SECONDS);
        } catch (Exception e) {
            return "上传失败";
        }

    }


  /*  public String uploadNew(MultipartFile file, String username, HttpServletRequest request) throws IOException {
        FileEntity fileEntity = new FileEntity();
        LocalDateTime date2 = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
        fileEntity.setDate(date2);
        String token = request.getHeader("Authorization");
        String belong = JwtUtils.getClaimsByToken(token).getSubject();
        fileEntity.setBelong(belong);
        // 上传文件路径
        String filePath = upf1sh.getUploadPath();
        String fileName = FileUploadUtils.upload(filePath, file);
        String url = serverConfigs.getUrl() + fileName;
        fileEntity.setName(fileName);

        fileEntity.setPath(url);
        fileMapper.insert(fileEntity);
        return fileEntity.getPath();

    }*/

    /**
     * 接收快照
     * 2023/7/11 16:19
     * UpF1sh
     *
     * @param file
     * @return
     */
    public String uploadSnapshot(MultipartFile file) {

        String originalFilename = file.getOriginalFilename();
//        String newFileName = UUID.randomUUID().toString().replace("-", "") + originalFilename;
//        String[] l = originalFilename.split("\\.");
        String dirPath = ("/data");
        String path = "/" + "Snapshot" + "/" + originalFilename;
        File destFile = new File(dirPath + path);
        if (!destFile.getParentFile().exists()) {
            destFile.getParentFile().mkdirs();
        }
        try {
            file.transferTo(destFile);
            return path;
        } catch (IOException e) {
            return null;
        }
    }

    public String uploadVideo(MultipartFile file, String belong) {

        String originalFilename = file.getOriginalFilename();
        String newFileName = UUID.randomUUID().toString().replace("-", "") + originalFilename;
        String[] l = originalFilename.split("\\.");
        String dirPath = ("/data");
        String path = "/" + "Snapshot" + "/" + newFileName;
        File destFile = new File(dirPath + path);
        if (!destFile.getParentFile().exists()) {
            destFile.getParentFile().mkdirs();
        }
        try {
            file.transferTo(destFile);
            return path;
        } catch (IOException e) {
            return null;
        }
    }

    public String uploadAudio(MultipartFile file) {

        String originalFilename = file.getOriginalFilename();
//        String newFileName = UUID.randomUUID().toString().replace("-", "") + originalFilename;
//        String[] l = originalFilename.split("\\.");
        String dirPath = ("/data");
        String path = "/" + "Snapshot" + "/" + originalFilename;
        File destFile = new File(dirPath + path);
        if (!destFile.getParentFile().exists()) {
            destFile.getParentFile().mkdirs();
        }
        try {
            file.transferTo(destFile);
            return path;
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * 对指定路径下的所有文件进行按时间排序
     *
     * @param filePath
     * @return
     */
    public File[] orderByDate(String filePath) {
        File file = new File(filePath);
        File[] files = file.listFiles();
        Arrays.sort(files, new Comparator<File>() {
            public int compare(File f1, File f2) {
                long diff = f1.lastModified() - f2.lastModified();
                if (diff > 0)
                    return -1;
                else if (diff == 0)
                    return 0;
                else
                    return 1;//如果 if 中修改为 返回-1 同时此处修改为返回 1  排序就会是递减,如果 if 中修改为 返回1 同时此处修改为返回 -1  排序就会是递增,
            }

            public boolean equals(Object obj) {
                return true;
            }

        });
        return files;

    }

    /**
     * 上传文件夹
     *
     * @param file
     */
    public void uploadCategory(MultipartFile[] file, String name) {
        System.out.println("总文件数" + file.length);
        if (file != null && file.length > 0) {
            for (MultipartFile temp : file) {
                System.out.println(temp.getOriginalFilename());
                System.out.println("大小" + temp.getSize());
                double size = temp.getSize();
                size = size / 1048576;
                FileEntity file_entity = new FileEntity();
                //处理上传的文件
                String originalFilename = temp.getOriginalFilename();
                Date date = new Date();
                LocalDateTime date1 = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String newFileName = UUID.randomUUID().toString().replace("-", "") + originalFilename;
                file_entity.setDate(date1);
                file_entity.setName(originalFilename);
                file_entity.setSize(size);
                String[] l = originalFilename.split("\\.");
                file_entity.setType(l[l.length - 1]);
                String dirPath = ("/data");
//                String dirPath = System.getProperty("user.dir");
                String path = "/" + "file" + "/" + newFileName;
                File destFile = new File(dirPath + path);
                file_entity.setPath("/data" + path);
                file_entity.setBelong(name);
                if (!destFile.getParentFile().exists()) {
                    destFile.getParentFile().mkdirs();
                }
                try {
                    temp.transferTo(destFile);
                    fileMapper.insert(file_entity);
                } catch (IOException e) {
                    System.out.println(e);
                }
                //其他逻辑
            }
        }

    }

    /**
     * 上传文件夹
     * UpF1sh
     * 2023/4/22 21:30
     */
    public boolean uploadSoundCode(List<MultipartFile> files, String name) throws IOException {
        for (MultipartFile file : files) {
            double size = file.getSize();
            size = size / 1048576;
            FileEntity file_entity = new FileEntity();
            String fileName = file.getOriginalFilename();
//            Date date = new Date();?
            LocalDateTime date1 = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
//            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String newFileName = UUID.randomUUID().toString().replace("-", "") + fileName;
            file_entity.setDate(date1);
            file_entity.setBelong(name);
            file_entity.setName(fileName);
            file_entity.setType(file.getContentType());
            file_entity.setSize(size);
            if (StrUtil.isBlank(fileName)) {
                continue;
            }
            //上传后的URL全路径
            String path = "/data" + "/" + "file" + "/" + newFileName;
//            File destFile = new File(dirPath + path);
            file_entity.setPath(path);
            fileMapper.insert(file_entity);
            FileUtil.writeFromStream(file.getInputStream(), path).length();
        }
        return true;
    }


    /**
     * 删除文件
     *
     * @param path
     * @return
     */

    public int delete(String path) {
        File file = new File(path);
        String username = user_info.getUsername();
        FileEntity dbFile = fileMapper.findByPath(path);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (dbFile.getBelong().equals(username)) {
            if (file.exists() && file.isFile()) {
                if (file.delete()) {
                    fileMapper.deleteFile_entity(path);
                    return 1;
                    //删除成功
                } else {
                    return 2;
                    //删除失败
                }
            } else
                return 4;
            //文件不存在
        } else {
            return 3;
//            Result.error().data("error", "无此权限");
        }

    }

    /**
     * 分页查询 数据库中的files
     * 2023/4/18 17:41
     * UpF1sh
     *
     * @param page
     * @return
     */
    public Page<FileEntity> findAllInDBByPage(Page<FileEntity> page, String belong) {
//      调用basemapper的分页查询方法
        QueryWrapper<FileEntity> wrapper = new QueryWrapper<FileEntity>()
                .eq("belong", belong);
        return fileMapper.selectPage(page, wrapper);
    }

    /**
     * 普通查询
     * UpF1sh
     * 2023/4/18 18:04
     *
     * @return
     */
    public List<FileEntity> findAllInDB() {
//      调用basemapper的分页查询方法
        return fileMapper.selectList(null);
    }

    /**
     * 查询上传者
     * UpF1sh
     * 2023/4/20 21:44
     */
    public String[] GetOwner() {
        return fileMapper.Owner();
    }

    public FileEntity findByFileName(String fileName) {
        return fileMapper.findByFileName(fileName);
    }

    //    HttpServletResponse response,
    public byte[] fileDownload(String path, String fileName, HttpServletResponse response) throws IOException {
        File file = new File(path);

        FileInputStream in = new FileInputStream(path);
        byte[] readBytes = IOUtils.toByteArray(in);
////        File file = new File(path);
//        if (!in.exists()) {
//            System.out.println("文件不存在!");
//            return null;
//        }
//        response.reset();
////        response.setContentType("application/force-download");
        response.setContentType("application/octet-stream");
//
////        response.setContentType("application/multipart/form-data");
////        response.setCharacterEncoding("utf-8");
//        String name = URLEncoder.encode(fileName, "UTF-8");
        response.setContentLength(readBytes.length);
//        response.addHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
//        byte[] readBytes = FileUtil.readBytes(file);
//        byte[] readBytes = FileUtil.readBytes(file);
//        System.out.println("type"+readBytes.getClass().toString());
//        FileUtils.readFileToByteArray(file)
//        OutputStream os = response.getOutputStream();
//        os.write(readBytes);
//        System.out.println("下载成功!");
        return readBytes;

    }


}

